package com.ping.shiro;

import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.mgt.SecurityManager;
import com.ping.redis.RedisSessionDao;

/**
 * shiro 的配置类
 * 
 * @author 浩子 2018年10月17日
 */
@Component
public class ShiroConfiguration {

	@Autowired
	private RedisSessionDao redisSessionDao;
	@Autowired
	private MyShiroRealm myShiroRealm;

	/**
	 * 注册securityManager，shiro通过securityManager来进行认证
	 * 
	 * @return
	 */
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(myShiroRealm);
		securityManager.setSessionManager(sessionManager());
		return securityManager;
	}

	/**
	 * 会话管理
	 * 
	 * @return
	 */
	@Bean
	public SessionManager sessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		sessionManager.getSessionIdCookie().setName("JSID"); // 设置一个cookie
		sessionManager.setSessionDAO(redisSessionDao);
		sessionManager.setGlobalSessionTimeout(7200000); // 最大存活时间
		return sessionManager;
	}

	/**
	 * 注册ShiroFilter 过滤器
	 * 
	 * @param securityManager
	 * @return
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {

		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		
		//自己的过滤器替代authc过滤器
		Map<String,Filter> filterMap = new LinkedHashMap<>();
        //自己的过滤器替代authc过滤器
        filterMap.put("authc",loginFilter());
        //添加自己的过滤器
        filterMap.put("perms",myAuthorizationFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

		/*
		 * 定义一个过滤链，里面放置url跟权限，就相当于原来的配置文件
		 * 过滤链里面的内容用一个map来放置
		 */
		Map<String, String> filterChainDefinitionMap = new HashMap<>();
		filterChainDefinitionMap.put("/**", "authc");
		filterChainDefinitionMap.put("/userInfo", "perms[admin:listUser]");
		filterChainDefinitionMap.put("/addUser", "perms[test1:addUser]");
		
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);// 设置过滤器链
		return shiroFilterFactoryBean;

	}
	
	/**
	 * 授权属性库，进行授权，shiro交给SecurityManager来处理
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}
	
	/**
	 * 配置自定义的登陆过滤器（可有可无）
	 * @return
	 */
	@Bean
	public LoginFilter loginFilter(){
		return new LoginFilter();
	}
	
	 /**
     * 配置自己的验证过滤器
     * @return
     */
    @Bean
    public MyAuthorizationFilter myAuthorizationFilter()
    {
        return new MyAuthorizationFilter();
    }
	

}
